package module1.main;

import java.util.*;

/**
 * This classes contains functionality for finding all the palindroms from the
 * given string and for outputting them into System.out
 * stream.
 * 
 * @author Dranik Vladimir
 */
public class PalindromeSearcher {
    private static final int MIN_PALINDROME_LENGTH = 3;
    private static final String MESSAGE_INPUT_LINE = "Please enter a set of symbols, letters, numbers (the minimum number of characters to search the palindrome %d):\n";
    private static final String MESSAGE_PALINDROMES_NOT_FOUND = "Palindromes not found!";
    private static final String MESSAGE_FOUND_PALINDROMES = "Found palindromes:";
    private static final String ERROR_PALINDROMES_ARE_NULL = "Palindromes are NULL!";
    
    /**
     * In this method (it is executed on programs startup) we use the facilities
     * of Scanner and PalindromSearcher classes to read the line from the
     * console, to find palindromes in it and to write the results to System.out
     * stream.
     * 
     * @param args - arguments passed from the command line
     *            
     */
    public static void main(String[] args) {
	String line = null;

	do {
	    line = inputLine();
	} while (checkMinimumInputSymbols(line));

	printPalindromes(searchPalindromes(line));
    }

    /**
     * Method provides an opportunity to enter a string
     * 
     * @return String - input string line
     */
    public static String inputLine() {
	System.out.printf(MESSAGE_INPUT_LINE, MIN_PALINDROME_LENGTH);
	Scanner scanner = new Scanner(System.in);
	return scanner.nextLine();
    }

    /**
     * Method checks the string to the minimum number of symbols
     * 
     * @return boolean 
     */
    public static boolean checkMinimumInputSymbols(String line) {
	if (line == null) {
	    return false;
	}

	if (line.length() < MIN_PALINDROME_LENGTH) {
	    return true;
	}
	return false;
    }

    /**
     * Method of finding palindromes
     * 
     * @param line - a string line in which the search for palindromes
     * @return Set<String> - list of found palindromes
     */
    public static Set<String> searchPalindromes(String line) {
	if (line == null) {
	    return null;
	}

	StringBuilder normalLine = null;
	StringBuilder reverseLine = null;

	Set<String> palindromes = new TreeSet<String>();
	for (int i = 0; i < line.length(); i++) {
	    for (int k = i + MIN_PALINDROME_LENGTH; k < line.length() + 1; k++) {
		normalLine = new StringBuilder(line.substring(i, k));
		reverseLine = new StringBuilder(normalLine).reverse();

		if (normalLine.toString().equals(reverseLine.toString())) {
		    palindromes.add(normalLine.toString());
		}
	    }
	}
	return palindromes;
    }

    /**
     * This method print results
     * 
     * @param palindromes - list of palindromes
     */
    public static void printPalindromes(Set<String> palindromes) {
	if (isNull(palindromes)) {
	    System.out.println(ERROR_PALINDROMES_ARE_NULL);
	    return;
	}

	if (isEmpty(palindromes)) {
	    System.out.println(MESSAGE_PALINDROMES_NOT_FOUND);
	    return;
	}

	System.out.println(MESSAGE_FOUND_PALINDROMES);
	for (String palindrome : palindromes) {
	    System.out.println(palindrome);
	}
    }

    private static boolean isNull(Set<String> palindromes) {
	if (palindromes == null) {
	    return true;
	}
	return false;
    }

    private static boolean isEmpty(Set<String> palindromes) {
	if (palindromes.size() == 0) {
	    return true;
	}
	return false;
    }
}
